﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FranceTriple.Dal
{
    public class ForumPostDal
    {
        public static String[] GetAuthors(String AnonymousID)
        {
            String[] result;
 
            List<Int32> idsAllowed = UserAccessDal.ForumIdAllowed(AnonymousID);

            using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
            {

                var postsAllowed = (from post in ctx.ForumPostSet.Include("ForumPostRead").Include("ForumTopic").Include("ForumTopic.ForumCategory").Include("ForumTopic.ForumCategory.Forum")
                                    where idsAllowed.Contains(post.ForumTopic.ForumCategory.Forum.Id)
                                    select post);

                result = (from p in postsAllowed
                          group p.PostMessage.Author by p.PostMessage.Author into list
                          orderby list.Key
                          select list.Key).ToArray();               
            }
            return result;
        }
        public static string GetSmilies()
        {
            StringBuilder sb;
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    sb = new StringBuilder();
                    var query = (from sml in ctx.ForumSmilieSet
                                 where sml.IsUsedForComposed
                                 select sml);
                    foreach (ForumSmilie sml in query)
                    {
                        sb.AppendLine(String.Format("<span style=\"cursor: hand;\" onclick=\"DoForumSmilie(' {0} ','Message');\"><img src=\"{1}\" border=\"0\" /></span>&nbsp;"
                            , sml.CodeSmilie,sml.ImageFileName));
                    }
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "Smilie", ex.Message), ex) { EntityType = typeof(Smilie) };
            }
            return sb.ToString();
        }

        public static string ReplaceSmiliesTextToImage(string p)
        {
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    foreach (ForumSmilie sml in ctx.ForumSmilieSet)
                    {
                        p = p.Replace(sml.CodeSmilie, String.Format("<img src=\"{0}\" border=\"0\" alt=\"\" />", sml.ImageFileName));
                    }
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "ForumSmilie", ex.Message), ex) { EntityType = typeof(ForumSmilie) };
            }
            return p;
        }
        /// <summary>
        /// Mark Read, all Post for one topic for one user
        /// </summary>
        /// <param name="UserId"></param>
        public static Boolean MarkAsRead(Int32 ForumTopicId, Guid UserId)
        {
            Boolean result = false;
            Int32 nbPost = 0;
            Int32 nbPostMarkAsRead = 0;

            using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
            {
                foreach (ForumPost post in ctx.ForumPostSet.Include("ForumPostRead").Where(p => p.ForumTopic.Id == ForumTopicId))
                {
                    nbPost++;
                    var query = (from r in post.ForumPostRead
                                 where r.UserId == UserId
                                 select r.Id).Count();
                    if (query == 0)
                    {
                        post.ForumPostRead.Add(new ForumPostRead() { UserId = UserId });
                        nbPostMarkAsRead++;
                    }
                }
                ctx.SaveChanges();
            }
            if (nbPost!=0 && nbPost == nbPostMarkAsRead)
                result = true;
            return result;
        }
        /// <summary>
        /// Mark Read, all Post of all topic for one user
        /// </summary>
        /// <param name="UserId"></param>
        public static Int32 MarkAllAsRead(Guid UserId)
        {
            using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
            {
                Int32 TotalMarkedMessage = 0;

                List<Int32> idsAllowed = UserAccessDal.ForumIdAllowed("");

                var postsAllowed = (from post in ctx.ForumPostSet.Include("ForumPostRead").Include("ForumTopic").Include("ForumTopic.ForumCategory").Include("ForumTopic.ForumCategory.Forum")
                             where idsAllowed.Contains(post.ForumTopic.ForumCategory.Forum.Id)
                             select post);
                
                foreach (ForumPost post in postsAllowed)
                {
                    var query = (from r in post.ForumPostRead
                                 where r.UserId == UserId
                                 select r.Id).Count();
                    if (query == 0)
                    {
                        post.ForumPostRead.Add(new ForumPostRead() { UserId = UserId });
                        TotalMarkedMessage++;
                    }
                }
                ctx.SaveChanges();
                return TotalMarkedMessage;
            }
        }
        /// <summary>
        /// Mark Unread, all Post of all topic for one user
        /// </summary>
        /// <param name="UserId"></param>
        public static void MarkAllAsUnread(Guid UserId)
        {
            using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
            {
                foreach (ForumPost post in ctx.ForumPostSet.Include("ForumPostRead").Where(p => p.ForumPostRead.Where(r => r.UserId == UserId).Count() > 0))
                {
                    post.ForumPostRead.Clear();
                }
                ctx.SaveChanges();
            }
        }

        public static Int32 GetPostIdPageNumber(Int32 ForumTopicId, Int32 ForumPostId, Int32 PageSize)
        {
            Int32 result = 1;
            using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
            {
                var query = (from p in ctx.ForumPostSet.Where(p1 => p1.ForumTopic.Id == ForumTopicId)
                             select p.Id).ToList().Count;

                result = (query / PageSize);


                if (result * PageSize < query)
                    result++;
            }
            return result;
        }

        //Todo : function autolink !!!
        public static String AutoLink(string p)
        {
            //Regex regx = new Regex("[^\">](http://[\\S]+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);

            //MatchCollection matches = regx.Matches(p);
            //foreach (Match match in matches)
            //{
            //    p = p.Replace(match.Value, "<a href='" + match.Value + "' target=\"_blank\">" + match.Value + "</a>");
            //}

            return p;            




            //String regex = @"(mailto\:|(news|(ht|f)tp(s?))\://)(([^[:space:]]+)|([^[:space:]]+)( #([^#]+)#)?)";  
            //Regex r = new Regex(regex, RegexOptions.IgnoreCase); 
            //return r.Replace(p, "<a href=\"$1\" title=\"Click to open in a new window or tab\" target=\"&#95;blank\">$1</a>").Replace("href=\"www", "href=\"http://www");

            //Regex patternUrl = null;
            //Match matchers = null;
            //String url = @"^(([\\w]+)?:\\/)?\\/?([^:\\/\\s]+)((\\/\\w+)*?\\/)?([\\w\\-\\.]+[^#?\\s]+)(.*)?(#[\\w\\-]+)?$";
            //String linkBefore = "<a href=\"";
            //String linkMiddleOne = "\" title=\"";
            //String linkMiddleTwo = "\" target=\"_blank\">";
            //String linkAfter = "</a>";
            //String output, protocol;
            //try
            //{
            //    //patternUrl = Pattern.compile(url);
            //    //matchers = patternUrl.matcher(p);
            //    patternUrl = new Regex(url);
            //    matchers = patternUrl.Match(p);
            //    Boolean found = matchers.Success;
            //    while (found)
            //    {                    
            //        if (matchers.Groups[1] != null)
            //        {
            //            if (matchers.Groups[1].Value.Contains("http") == true || matchers.Groups[1].Value.Contains("ftp") == true)
            //            {
            //                output = linkBefore + matchers.Value + linkMiddleOne + matchers.Value.ToUpper() +
            //                                linkMiddleTwo + matchers.Value + linkAfter;
            //            }
            //            else
            //            {
            //                protocol = "http://";
            //                output = linkBefore + protocol + matchers.Value + linkMiddleOne + matchers.Value.ToUpper() +
            //                                linkMiddleTwo + matchers.Value + linkAfter;
            //            }
            //        }
            //        else if (matchers.Groups[1] == null && matchers.Groups[2] == null && matchers.Groups[7].Value.CompareTo(String.Empty) == 0)
            //        {
            //            if (matchers.Groups[3].Value.Contains("ftp") == true)
            //            {
            //                protocol = "ftp://";
            //            }
            //            else
            //            {
            //                protocol = "http://";
            //            }
            //            output = linkBefore + protocol + matchers.Value + linkMiddleOne + matchers.Value.ToUpper() +
            //                            linkMiddleTwo + matchers.Value + linkAfter;
            //        }
            //        else if (matchers.Groups[7] != null)
            //        {
            //            output = matchers.Value;
            //        }
            //        if (!found)
            //        {
            //            output = p;
            //        }
            //        found = matchers.Success;
            //    }
            //}
            //catch (Exception ex)
            //{
            //    LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
            //    throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "ForumPost", ex.Message), ex) { EntityType = typeof(ForumPost) };
            //}
            //return p;

            // string pattern;
            //pattern= @"/\b((?P<protocol>(https?)|(ftp)):\/\/)?(?P<domain>[-A-Z0-9\\.]+)[.][A-Z]{2,7}(([:])?([0-9]+)?)(?P<file>\/[-A-Z0-9+&@#\/%=~_|!:,\\.;]*)?(?P<parameters>\?[A-Z0-9+&@#\/%=~_|!:,\\.;]*)?/ise";
            //pattern= @"/\b(?P&lt;protocol&gt;https?|ftp):\/\/(?P&lt;domain&gt;[-A-Z0-9.]+)(([:])?([0-9]+)?)(?P&lt;file&gt;\/[-A-Z0-9+&amp;@#\/%=~_|!:,.;]*)?(?P&lt;parameters&gt;\?[A-Z0-9+&amp;@#\/%=~_|!:,.;]*)?/i";
            //p = preg_replace($pattern, "' <a href=\"'.htmlspecialchars('$0').'\">$0</a>'", p); 
            //p = Regex.Replace(p, pattern, "' <a href=\"'.htmlspecialchars('$0').'\">$0</a>'");
            // fix URLs without protocols 
            //p = preg_replace("#href='www#i", "href='http://www"); 
            //p = Regex.Replace(p, "#href='www#i", "href='http://www");
            //p = preg_replace("#href=['\"](?!(https?|ftp)://)#i", "href='http://", p); 
            //p = Regex.Replace(p, "#href=['\"](?!(https?|ftp)://)#i", "href='http://");
            //return p;
        }

        public static ForumPost GetEntity(int entityID)
        {
            ForumPost fPost;

            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    fPost = (from p in ctx.ForumPostSet
                             where (p.Id == entityID)
                             select p).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "ForumPost", ex.Message), ex) { EntityType = typeof(ForumPost) };
            }
            return fPost;
        }

        public static int CreateEntity(ForumPost entity)
        {
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    ForumTopicDal fk = new ForumTopicDal();
                    ForumPost myPost = new ForumPost();

                    //CreationDate pourles imports uniquement
                    myPost.PostMessage = new MessageType()
                    {
                        Label = entity.PostMessage.Label,
                        Message = entity.PostMessage.Message,
                        Author = entity.PostMessage.Author,
                        AuthorAdressIp = entity.PostMessage.AuthorAdressIp,
                        CreationDate = entity.PostMessage.CreationDate
                    };

                    ctx.AddToForumPostSet(myPost);
                    myPost.ForumTopic = (ForumTopic)ctx.GetObjectByKey(entity.ForumTopic.EntityKey);

                    ctx.SaveChanges();

                    //Mettre à jour LastPostId pour la catégory correspondante
                    var catToUpdate = (from t in ctx.ForumTopicSet.Include("ForumCategory")
                                       where t.Id == myPost.ForumTopic.Id
                                       select t.ForumCategory).First();

                    if ((catToUpdate.LastPostCreationDate == null) || (catToUpdate.LastPostCreationDate < myPost.PostMessage.CreationDate))
                    {
                        catToUpdate.LastPostId = myPost.Id;
                        catToUpdate.LastPostCreationDate = myPost.PostMessage.CreationDate;
                        catToUpdate.LastPostAuthor = myPost.PostMessage.Author;
                        catToUpdate.LastPostTopicId = myPost.ForumTopic.Id;
                    }

                    catToUpdate.NumberOfMessage++;
                    ctx.SaveChanges();

                    if (UserProfile.GetUserProfile(entity.PostMessage.Author, true) != null)
                    {
                        UserProfile profile = UserProfile.GetUserProfile(entity.PostMessage.Author, true);
                        profile.NumberOfForumPost++;
                        profile.Save();
                    }

                    return myPost.Id;
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("InsertError".ToLocalizedString(), "ForumPost", ex.Message), ex) { EntityType = typeof(ForumPost) };
            }
        }

        public static void UpdateEntity(ForumPost entity)
        {
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    var postToUpdate = ctx.ForumPostSet.Where(p => p.Id == entity.Id).FirstOrDefault();
                    if (postToUpdate == null)
                    {
                        CreateEntity(entity);
                        return;
                    }
                    postToUpdate.PostMessage = new MessageType()
                        {
                            Label = entity.PostMessage.Label,
                            Message = entity.PostMessage.Message,
                            Author = entity.PostMessage.Author,
                            AuthorAdressIp = entity.PostMessage.AuthorAdressIp
                        };

                    ctx.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("UpdateError".ToLocalizedString(), "ForumPost", ex.Message), ex) { EntityType = typeof(ForumPost) };
            }
        }

        public static void DeleteEntity(int entityID)
        {
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    var postToUpdate = ctx.ForumPostSet.Include("ForumTopic").Include("ForumTopic.ForumCategory").Where(p => p.Id == entityID).FirstOrDefault();
                    if (postToUpdate == null)
                        return;

                    postToUpdate.ForumTopic.ForumCategory.NumberOfMessage--;

                    ctx.ForumPostSet.DeleteObject(postToUpdate);
                    ctx.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("DeleteError".ToLocalizedString(), "ForumPost", ex.Message), ex) { EntityType = typeof(ForumPost) };
            }
        }

        public static ForumPost[] GetEntities(string searchText)
        {
            ForumPost[] res;

            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    res = (from p in ctx.ForumPostSet
                           where p.PostMessage.Label.Contains(searchText)
                           orderby p.PostMessage.CreationDate descending
                           select p).ToArray();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "ForumPost", ex.Message), ex) { EntityType = typeof(ForumPost) };
            }
            return res;
        }
    }
}
